import Pool from './base/pool';

let instance;

/**
 * 全局状态管理器
 * 管理游戏中所有用到的数据
 */
export default class DataBus {
  constructor() {
    if (instance) return instance

    instance = this

    this.pool = new Pool()

    this.reset()
  }

  reset() {
    this.frame = 0
    this.score = 0
    this.gameOver = false
    
    // 象棋相关状态
    this.currentPlayer = 1 // 1: 红方, 2: 黑方
    this.board = [] // 9x10的象棋棋盘
    this.lastMove = null // 最后一步的位置
    this.winner = null // 获胜者
    this.gameStarted = false
    
    // 悔棋次数管理
    this.undoCounts = { 1: 3, 2: 3 } // 每个玩家3次悔棋机会
    this.moveHistory = [] // 记录落子历史，用于悔棋
    
    // 在线对战相关状态
    this.isOnlineMode = false
    this.isMyTurn = false
    this.myPlayer = 1 // 1=红方, 2=黑方
    this.opponentConnected = false
    this.roomId = null
    this.gameStarted = false
    
    // 人机对战相关状态
    this.isAIMode = false
    this.aiDifficulty = 'easy' // easy, medium, hard
    this.aiPlayer = 2 // AI默认执黑方
    
    // 初始化棋盘
    this.initBoard()
  }

  initBoard() {
    this.board = []
    for (let i = 0; i < 10; i++) {
      this.board[i] = []
      for (let j = 0; j < 9; j++) {
        this.board[i][j] = 0 // 0表示空位
      }
    }
    
    // 初始化红方棋子（下方）
    this.board[9][0] = { type: 'che', player: 1 } // 车
    this.board[9][1] = { type: 'ma', player: 1 } // 马
    this.board[9][2] = { type: 'xiang', player: 1 } // 相
    this.board[9][3] = { type: 'shi', player: 1 } // 士
    this.board[9][4] = { type: 'jiang', player: 1 } // 将
    this.board[9][5] = { type: 'shi', player: 1 } // 士
    this.board[9][6] = { type: 'xiang', player: 1 } // 相
    this.board[9][7] = { type: 'ma', player: 1 } // 马
    this.board[9][8] = { type: 'che', player: 1 } // 车
    this.board[7][1] = { type: 'pao', player: 1 } // 炮
    this.board[7][7] = { type: 'pao', player: 1 } // 炮
    this.board[6][0] = { type: 'bing', player: 1 } // 兵
    this.board[6][2] = { type: 'bing', player: 1 } // 兵
    this.board[6][4] = { type: 'bing', player: 1 } // 兵
    this.board[6][6] = { type: 'bing', player: 1 } // 兵
    this.board[6][8] = { type: 'bing', player: 1 } // 兵
    
    // 初始化黑方棋子（上方）
    this.board[0][0] = { type: 'che', player: 2 } // 车
    this.board[0][1] = { type: 'ma', player: 2 } // 马
    this.board[0][2] = { type: 'xiang', player: 2 } // 相
    this.board[0][3] = { type: 'shi', player: 2 } // 士
    this.board[0][4] = { type: 'jiang', player: 2 } // 将
    this.board[0][5] = { type: 'shi', player: 2 } // 士
    this.board[0][6] = { type: 'xiang', player: 2 } // 相
    this.board[0][7] = { type: 'ma', player: 2 } // 马
    this.board[0][8] = { type: 'che', player: 2 } // 车
    this.board[2][1] = { type: 'pao', player: 2 } // 炮
    this.board[2][7] = { type: 'pao', player: 2 } // 炮
    this.board[3][0] = { type: 'bing', player: 2 } // 兵
    this.board[3][2] = { type: 'bing', player: 2 } // 兵
    this.board[3][4] = { type: 'bing', player: 2 } // 兵
    this.board[3][6] = { type: 'bing', player: 2 } // 兵
    this.board[3][8] = { type: 'bing', player: 2 } // 兵
  }

  /**
   * 检查是否获胜（将军被吃）
   */
  checkWin(row, col, player) {
    // 检查是否吃掉了对方的将/帅
    const opponent = player === 1 ? 2 : 1
    let hasJiang = false
    
    for (let i = 0; i < 10; i++) {
      for (let j = 0; j < 9; j++) {
        if (this.board[i][j] && this.board[i][j].type === 'jiang' && this.board[i][j].player === opponent) {
          hasJiang = true
          break
        }
      }
    }
    
    return !hasJiang
  }

  /**
   * 检查是否和棋（简化版）
   */
  checkDraw() {
    // 简化版和棋检查：如果双方都只剩下将/帅，则和棋
    let redPieces = 0
    let blackPieces = 0
    
    for (let i = 0; i < 10; i++) {
      for (let j = 0; j < 9; j++) {
        if (this.board[i][j]) {
          if (this.board[i][j].player === 1) {
            redPieces++
          } else {
            blackPieces++
          }
        }
      }
    }
    
    return redPieces === 1 && blackPieces === 1
  }

  /**
   * 切换玩家
   */
  switchPlayer() {
    this.currentPlayer = this.currentPlayer === 1 ? 2 : 1
  }

  /**
   * 重新开始游戏
   */
  restart() {
    this.currentPlayer = 1
    this.lastMove = null
    this.winner = null
    this.gameOver = false
    this.gameStarted = false
    this.undoCounts = { 1: 3, 2: 3 }
    this.moveHistory = []
    this.initBoard()
  }

  /**
   * 获取玩家悔棋次数
   */
  getUndoCount(player) {
    return this.undoCounts[player] || 0
  }

  /**
   * 使用悔棋
   */
  useUndo(player) {
    if (this.undoCounts[player] > 0) {
      this.undoCounts[player]--
      return true
    }
    return false
  }

  /**
   * 记录移动
   */
  recordMove(fromRow, fromCol, toRow, toCol, player, capturedPiece) {
    this.moveHistory.push({
      from: { row: fromRow, col: fromCol },
      to: { row: toRow, col: toCol },
      player: player,
      capturedPiece: capturedPiece,
      timestamp: Date.now()
    })
  }

  /**
   * 悔棋
   */
  undoLastMove() {
    if (this.moveHistory.length === 0) return false
    
    const lastMove = this.moveHistory.pop()
    
    // 恢复移动
    this.board[lastMove.from.row][lastMove.from.col] = this.board[lastMove.to.row][lastMove.to.col]
    this.board[lastMove.to.row][lastMove.to.col] = lastMove.capturedPiece
    
    // 切换回上一个玩家
    this.currentPlayer = lastMove.player
    
    return true
  }

  /**
   * 悔棋AI的移动（撤销两步：AI移动和玩家移动）
   */
  undoAIMoves() {
    let undoCount = 0
    // 撤销两步：AI的移动和玩家的移动
    while (this.moveHistory.length > 0 && undoCount < 2) {
      this.undoLastMove()
      undoCount++
    }
    
    // 确保回到玩家回合
    this.currentPlayer = this.aiPlayer === 1 ? 2 : 1
  }

  /**
   * 检查是否可以悔棋
   */
  canUndo(player) {
    return this.getUndoCount(player) > 0 && this.moveHistory.length > 0
  }

  /**
   * 设置在线模式
   */
  setOnlineMode(isOnline, myPlayer = 1) {
    this.isOnlineMode = isOnline
    this.myPlayer = myPlayer
    this.isMyTurn = myPlayer === 1 // 红方先手
  }

  /**
   * 设置AI模式
   */
  setAIMode(isAI, difficulty = 'easy', aiPlayer = 2) {
    this.isAIMode = isAI
    this.aiDifficulty = difficulty
    this.aiPlayer = aiPlayer
  }

  /**
   * 设置对手连接状态
   */
  setOpponentConnected(connected) {
    this.opponentConnected = connected
  }

  /**
   * 设置房间ID
   */
  setRoomId(roomId) {
    this.roomId = roomId
  }

  /**
   * 设置是否轮到我的回合
   */
  setMyTurn(isMyTurn) {
    this.isMyTurn = isMyTurn
  }

  /**
   * 设置游戏开始状态
   */
  setGameStarted(started) {
    this.gameStarted = started
  }

  /**
   * 检查是否可以移动
   */
  canMakeMove() {
    if (this.gameOver) return false
    
    if (this.isOnlineMode) {
      return this.isMyTurn && this.opponentConnected
    }
    
    if (this.isAIMode) {
      return this.currentPlayer !== this.aiPlayer
    }
    
    return true
  }

  /**
   * 设置游戏结束
   */
  setGameOver(winner) {
    this.gameOver = true
    this.winner = winner
  }

  /**
   * 处理对手移动
   */
  handleOpponentMove(row, col, player) {
    // 在线对战中的对手移动处理
    this.board[row][col] = { type: 'unknown', player: player }
    this.currentPlayer = this.currentPlayer === 1 ? 2 : 1
  }

  /**
   * 检查移动是否合法
   */
  isValidMove(fromRow, fromCol, toRow, toCol, player) {
    const piece = this.board[fromRow][fromCol]
    if (!piece || piece.player !== player) return false
    
    // 检查目标位置是否在棋盘内
    if (toRow < 0 || toRow >= 10 || toCol < 0 || toCol >= 9) return false
    
    // 检查目标位置是否是自己的棋子
    const targetPiece = this.board[toRow][toCol]
    if (targetPiece && targetPiece.player === player) return false
    
    // 根据棋子类型检查移动规则
    return this.checkMoveRules(piece.type, fromRow, fromCol, toRow, toCol, player)
  }

  /**
   * 检查移动规则
   */
  checkMoveRules(pieceType, fromRow, fromCol, toRow, toCol, player) {
    switch (pieceType) {
      case 'jiang':
        return this.checkJiangMove(fromRow, fromCol, toRow, toCol, player)
      case 'shi':
        return this.checkShiMove(fromRow, fromCol, toRow, toCol, player)
      case 'xiang':
        return this.checkXiangMove(fromRow, fromCol, toRow, toCol, player)
      case 'ma':
        return this.checkMaMove(fromRow, fromCol, toRow, toCol, player)
      case 'che':
        return this.checkCheMove(fromRow, fromCol, toRow, toCol, player)
      case 'pao':
        return this.checkPaoMove(fromRow, fromCol, toRow, toCol, player)
      case 'bing':
        return this.checkBingMove(fromRow, fromCol, toRow, toCol, player)
      default:
        return false
    }
  }

  /**
   * 将/帅移动规则
   */
  checkJiangMove(fromRow, fromCol, toRow, toCol, player) {
    const rowDiff = Math.abs(toRow - fromRow)
    const colDiff = Math.abs(toCol - fromCol)
    
    // 只能在九宫格内移动
    const isRed = player === 1
    const minRow = isRed ? 7 : 0
    const maxRow = isRed ? 9 : 2
    const minCol = 3
    const maxCol = 5
    
    if (toRow < minRow || toRow > maxRow || toCol < minCol || toCol > maxCol) {
      return false
    }
    
    // 只能横向或纵向移动一格
    return (rowDiff === 1 && colDiff === 0) || (rowDiff === 0 && colDiff === 1)
  }

  /**
   * 士移动规则
   */
  checkShiMove(fromRow, fromCol, toRow, toCol, player) {
    const rowDiff = Math.abs(toRow - fromRow)
    const colDiff = Math.abs(toCol - fromCol)
    
    // 只能在九宫格内移动
    const isRed = player === 1
    const minRow = isRed ? 7 : 0
    const maxRow = isRed ? 9 : 2
    const minCol = 3
    const maxCol = 5
    
    if (toRow < minRow || toRow > maxRow || toCol < minCol || toCol > maxCol) {
      return false
    }
    
    // 只能斜着走一格
    return rowDiff === 1 && colDiff === 1
  }

  /**
   * 相/象移动规则
   */
  checkXiangMove(fromRow, fromCol, toRow, toCol, player) {
    const rowDiff = Math.abs(toRow - fromRow)
    const colDiff = Math.abs(toCol - fromCol)
    
    // 只能斜着走两格
    if (rowDiff !== 2 || colDiff !== 2) return false
    
    // 不能过河
    const isRed = player === 1
    if (isRed && toRow < 5) return false
    if (!isRed && toRow > 4) return false
    
    // 检查象眼是否被堵
    const eyeRow = (fromRow + toRow) / 2
    const eyeCol = (fromCol + toCol) / 2
    return !this.board[eyeRow][eyeCol]
  }

  /**
   * 马移动规则
   */
  checkMaMove(fromRow, fromCol, toRow, toCol, player) {
    const rowDiff = Math.abs(toRow - fromRow)
    const colDiff = Math.abs(toCol - fromCol)
    
    // 马走日
    if (!((rowDiff === 2 && colDiff === 1) || (rowDiff === 1 && colDiff === 2))) {
      return false
    }
    
    // 检查马脚是否被堵
    let legRow, legCol
    if (rowDiff === 2) {
      legRow = fromRow + (toRow > fromRow ? 1 : -1)
      legCol = fromCol
    } else {
      legRow = fromRow
      legCol = fromCol + (toCol > fromCol ? 1 : -1)
    }
    
    return !this.board[legRow][legCol]
  }

  /**
   * 车移动规则
   */
  checkCheMove(fromRow, fromCol, toRow, toCol, player) {
    const rowDiff = Math.abs(toRow - fromRow)
    const colDiff = Math.abs(toCol - fromCol)
    
    // 车只能直线移动
    if (rowDiff !== 0 && colDiff !== 0) return false
    
    // 检查路径上是否有其他棋子
    const minRow = Math.min(fromRow, toRow)
    const maxRow = Math.max(fromRow, toRow)
    const minCol = Math.min(fromCol, toCol)
    const maxCol = Math.max(fromCol, toCol)
    
    for (let i = minRow; i <= maxRow; i++) {
      for (let j = minCol; j <= maxCol; j++) {
        if (i === fromRow && j === fromCol) continue
        if (i === toRow && j === toCol) continue
        if (this.board[i][j]) return false
      }
    }
    
    return true
  }

  /**
   * 炮移动规则
   */
  checkPaoMove(fromRow, fromCol, toRow, toCol, player) {
    const rowDiff = Math.abs(toRow - fromRow)
    const colDiff = Math.abs(toCol - fromCol)
    
    // 炮只能直线移动
    if (rowDiff !== 0 && colDiff !== 0) return false
    
    // 计算路径上的棋子数量
    let pieceCount = 0
    const minRow = Math.min(fromRow, toRow)
    const maxRow = Math.max(fromRow, toRow)
    const minCol = Math.min(fromCol, toCol)
    const maxCol = Math.max(fromCol, toCol)
    
    for (let i = minRow; i <= maxRow; i++) {
      for (let j = minCol; j <= maxCol; j++) {
        if (i === fromRow && j === fromCol) continue
        if (i === toRow && j === toCol) continue
        if (this.board[i][j]) pieceCount++
      }
    }
    
    const targetPiece = this.board[toRow][toCol]
    
    // 移动时不能有棋子，吃子时必须翻过一个棋子
    if (targetPiece) {
      return pieceCount === 1
    } else {
      return pieceCount === 0
    }
  }

  /**
   * 兵/卒移动规则
   */
  checkBingMove(fromRow, fromCol, toRow, toCol, player) {
    const rowDiff = toRow - fromRow
    const colDiff = Math.abs(toCol - fromCol)
    
    const isRed = player === 1
    
    // 兵只能向前移动一格，过河后可以左右移动一格
    if (colDiff > 1) return false
    
    if (isRed) {
      // 红方兵 - 向上移动（rowDiff < 0）
      if (rowDiff > 0 || rowDiff < -1) return false
      if (rowDiff === 0 && colDiff === 1) {
        // 左右移动只能在过河后（红方过河是指 row <= 4）
        return fromRow <= 4
      }
    } else {
      // 黑方卒 - 向下移动（rowDiff > 0）
      if (rowDiff < 0 || rowDiff > 1) return false
      if (rowDiff === 0 && colDiff === 1) {
        // 左右移动只能在过河后（黑方过河是指 row >= 5）
        return fromRow >= 5
      }
    }
    
    return true
  }
}
